package configs

import (
	"gorm.io/datatypes"
	"github.com/guregu/null"
	"gorm.io/gorm"
	"time"
)

// 项目模型
type FormSchema struct {
	ID              uint     `gorm:"primaryKey" json:"id"`
	TableName       string   `json:"tablename" gorm:"column:tablename;type:varchar(255);unique;not null;index;comment:物理表名"`
	FormName        string `json:"formname" gorm:"column:formname;type:varchar(255);unique;not null;comment:表单名称" validate:"required,max=255"`
	Cxtj            datatypes.JSON `json:"cxtj" gorm:"type:json;comment:查询条件"`
	Kfcx            datatypes.JSON `json:"kfcx" gorm:"type:json;comment:显示列"`
	Kftb            datatypes.JSON `json:"kftb" gorm:"type:json;comment:开放填报"`
    StartTime       null.Time      `json:"starttime" gorm:"comment:开始时间"`
	EndTime         null.Time      `json:"endtime" gorm:"comment:结束时间"`
	Fields          datatypes.JSON `json:"fields" gorm:"type:json;comment:字段配置"`
	Mhcx            bool           `json:"mhcx" gorm:"comment:模糊查询"`
	Sfbt            bool           `json:"sfbt" gorm:"comment:是否必填"`
	Wytb            bool           `json:"wytb" gorm:"comment:唯一填报"`
	Jghp            bool           `json:"jghp" gorm:"comment:结果横排"`
	Xsxh            bool           `json:"xsxh" gorm:"comment:显示序号"`
	Glkz            bool           `json:"glkz" gorm:"comment:过滤空值"`
	Dblc            bool           `json:"dblc" gorm:"comment:多表联查"`
	Suoding         bool           `json:"suoding" gorm:"comment:锁定查询"`
	Glcx            string         `json:"glcx" gorm:"size:50;null;comment:关联查询"`
	Dblcxx          datatypes.JSON `json:"dblcxx" gorm:"type:json;comment:多表联查设置"`
	TemplateID      uint           `json:"templateId" gorm:"comment:页面模板ID"`
	MessageConfig   datatypes.JSON `json:"messageconfig" gorm:"type:json;comment:消息推送配置"`
	Zsmb            uint           `json:"zsmb" gorm:"comment:证书模板id"`
	Wordmb          string         `json:"wordmb" gorm:"type:varchar(255);null;comment:word模板"`
	Pxzd            datatypes.JSON `json:"pxzd" gorm:"type:json;comment:排序字段"`
	Remark          datatypes.JSON `json:"remark" gorm:"type:json;comment:查询须知"`
	Tby             datatypes.JSON `json:"tby" gorm:"type:json;comment:填报员"`
    ProcessConfig   datatypes.JSON `json:"processConfig" gorm:"type:json;comment:流程配置"`
    Reservation     datatypes.JSON `json:"reservation" gorm:"type:json;comment:预约配置"`
    IsReservation   bool           `json:"isReservation" gorm:"comment:是否启用预约"`
    EnableVerification bool        `json:"enableVerification" gorm:"comment:核销开关"`
    Qtxs            string         `json:"qtxs" gorm:"type:varchar(50);default:全开放;"`//前台显示1.全开放2.登录可见3.管理员4.指定填报员
    ProcessInstances []ProcessInstance `gorm:"foreignKey:FormID;constraint:OnDelete:CASCADE"` //关联流程
	CreatedBy       uint           `gorm:"comment:创建者"`
	CreatedAt       time.Time
	UpdatedAt       time.Time
}

// 字段配置
type FieldConfig struct {
	Type        string  `json:"type"`       // 控件类型：input/select/image
    Key         string  `json:"key"`        // 字段标识（例如：k0）
    Name        string  `json:"name"`       // 字段名如：姓名
    Placeholder string  `json:"placeholder"`// 提示文字
    Options     string  `json:"options"`    // 选项，可以用于文件类型、默认值等
    ZbOptions   []Zb    `json:"zboptions"`  // 子表
    SfzOptions  Sfz     `json:"sfzoptions"` // 身份证识别
    Required    bool    `json:"required"`   // 是否必填
    Edituser    []uint  `json:"edituser"`   // 可编辑的用户
    Help        string  `json:"help"`       // 帮助文本，解释字段的使用
    Color       string  `json:"color"`      // 列文字颜色
    Max         int     `json:"max"`        // 限制数量（用于 multiimage, multifile 类型）
    Size        int     `json:"size"`       // 文件大小限制（用于 file, multifile 类型）
    Kbtable     int     `json:"kbtable"`    //联动引用表
    Kbcxcol     string  `json:"kbcxcol"`    // 返回列
    Kbcxz       int     `json:"kbcxz"`      // 联动级数
    Kbfhcol     int     `json:"kbfhcol"`    // 当前级
    Condition   *DisplayCondition `json:"condition"` // 显示条件
}

// 显示条件
type DisplayCondition struct {
    Field  string       `json:"field"`  // 监听的字段名
    Value  interface{}  `json:"value"`  // 匹配的值
    Action string       `json:"action"` // 动作：show/hide
}

// 预约配置
type ReservationConfig struct {
    Mode          string             `json:"mode" validate:"required,oneof=dynamic static custom"`// 模式选择
    MaxDays       int                `json:"maxDays,omitempty"`                                   // 动态模式使用
    AllowedDates  []DateSlot         `json:"allowedDates,omitempty"`                              // 静态/自定义模式
    TimeSlots     []TimeSlot         `json:"timeSlots,omitempty"`                                 // 全局时段
    Extensions    datatypes.JSON     `json:"extensions,omitempty"`                                // 扩展配置
    AllowMultiple bool               `json:"allowMultiple,omitempty"`                             // 是否允许多个未过期预约
}

type ReservationExtensions struct {
    ExcludedDates []string `json:"excludedDates"`
}

type DateSlot struct {
    Date      string       `json:"date" validate:"required,datetime=2006-01-02"` // 日期格式校验
    TimeSlots []TimeSlot   `json:"timeSlots,omitempty"`                          // 自定义时段
}

type TimeSlot struct {
    Start      string `json:"start" validate:"required,datetime=15:04"` // HH:mm格式
    End        string `json:"end" validate:"required,datetime=15:04"`
    MaxPeople  int    `json:"maxPeople" validate:"min=0"`
}

type Zb struct {
    Bt      bool        `json:"bt"`
    Key     string      `json:"key"`
    Lx      string      `json:"lx"`
    Xx      string      `json:"xx"`
}

type Sfz struct {
    Name    string       `json:"name"`
    Sex     string       `json:"sex"`
    Mz      string       `json:"mz"`
    Day     string       `json:"day"`
    Ade     string       `json:"ade"`
    Old     string       `json:"old"`
}

//多表联查
type Dblcxx struct {
	ID          uint        `json:"id"`     //项目id
	Title       string      `json:"title"`  //小标题
	Order       int         `json:"order"`  //排序
}

// 流程实例表
type ProcessInstance struct {
    ID              uint      `gorm:"primaryKey"`
    FormID          uint      `gorm:"index;comment:关联表单ID"`
    DataID          uint      `gorm:"comment:业务数据ID"`
    Status          string    `gorm:"size:20;default:'processing';comment:状态:processing/approved/rejected/pending"`
    CurrentStep     int       `gorm:"default:1;comment:当前步骤"`
    InitiatorID     uint      `gorm:"comment:发起人ID"`
    //设置级联删除确保删除父表记录时自动删除关联的子表记录
    ApprovalRecords []ApprovalRecord `gorm:"foreignKey:InstanceID;constraint:OnDelete:CASCADE"` // 定义一对多关联到审批记录
    FormSchema      *FormSchema `gorm:"foreignKey:FormID;references:ID;constraint:OnDelete:CASCADE"` //关联项目
    Initiator       User        `gorm:"foreignKey:InitiatorID;references:ID"` // 关联发起人用户表
    CreatedAt       time.Time
    UpdatedAt       time.Time
}

// 审批记录表
type ApprovalRecord struct {
    ID              uint      `gorm:"primaryKey"`
    InstanceID      uint      `gorm:"index;comment:流程实例ID"`
    Step            int       `gorm:"comment:审批步骤"`
    ApproverID      uint      `gorm:"comment:审批人ID"`
    Status          string    `gorm:"size:20;default:'processing';comment:状态:processing/approved/rejected/pending"`
    Comment         string    `gorm:"type:text;comment:审批意见"`
    //设置级联删除确保删除父表记录时自动删除关联的子表记录
    ProcessInstance *ProcessInstance `gorm:"foreignKey:InstanceID;references:ID;constraint:OnDelete:CASCADE"` // 定义多对一关联到流程实例
    Approver        User      `gorm:"foreignKey:ApproverID;references:ID"` // 关联审批人用户
    CreatedAt       time.Time
    UpdatedAt       time.Time
}

type Wzconfig struct {
    Name    string       `json:"name"`
    Phone   string       `json:"phone"`
}

type FormListResponse struct {
    Config      Wzconfig        `json:"config"`
	Items       []FormSchema    `json:"items"`
	Total       int64           `json:"total"`
}

type FormQuery struct {
	Page     int    `json:"page"`
	PageSize int    `json:"pageSize"`
	Search   string `json:"search"`
}

// 页面模板数据模型
type Template struct {
	ID          uint            `gorm:"primaryKey" json:"id"`
	Name        string          `gorm:"size:50;not null" json:"name" binding:"required,min=2,max=50,excludesall=<>"`
	Config      datatypes.JSON  `gorm:"type:json;not null" json:"config" binding:"required"`
	IsDefault   bool            `gorm:"default:false" json:"is_default"`
	CreatedAt   time.Time
	UpdatedAt   time.Time
}

type TemplateConfig struct {
	Header struct {
		Image  string `json:"image" binding:"omitempty,url"`  // 表头图片URL
		Height int    `json:"height" binding:"min=0,max=500"` // 表头高度(px)
	} `json:"header"`
	Background struct {
		Image   string  `json:"image" binding:"omitempty,url"`    // 背景图URL
		Opacity float64 `json:"opacity" binding:"min=0,max=1"`    // 透明度(0-1)
	} `json:"background"`
	Title struct {
		FontSize int    `json:"font_size" binding:"min=12,max=48"` // 标题大小(px)
		Color    string `json:"color" binding:"hexcolor|rgb|rgba"` // 标题颜色
	} `json:"title"`
	Button struct {
		Text     string `json:"text" binding:"required,max=20"`      // 按钮文字
		Color    string `json:"color" binding:"hexcolor|rgb|rgba"`   // 文字颜色
		FontSize int    `json:"font_size" binding:"min=12,max=24"`   // 文字大小(px)
		BgColor  string `json:"bg_color" binding:"hexcolor|rgb|rgba"`// 背景颜色
		Radius   int    `json:"radius" binding:"min=0,max=50"`       // 按钮圆角(px)
		Padding  string `json:"padding" binding:"csslength"`         // 内边距
		Width    int    `json:"width" binding:"min=12,max=1000"`    // 长度(px)
	} `json:"button"`
}

// 首页diy
type HomeTemplate struct {
	ID              uint           `gorm:"primaryKey" json:"id"`
	Name            string         `gorm:"size:128;not null;default:'默认模板'" json:"name"`
	BackgroundColor string         `gorm:"size:32;default:'#ffffff'" json:"backgroundColor"`
	PagePadding     int            `gorm:"type:int;default:16" json:"pagePadding"`
	Components      datatypes.JSON `gorm:"type:json;not null" json:"components"`
	IsEnabled       bool           `gorm:"default:false" json:"is_enabled"` //是否启用
	CreatedAt       time.Time      `json:"createdAt"`
	UpdatedAt       time.Time      `json:"updatedAt"`
}

// 用户模型
// 普通用户不能进入后台，填报员只能看到自己的数据，项目管理员可看到全部数据，但根据noeditur中的userid判断是否可编辑字段
type User struct {
	ID          uint        `gorm:"primaryKey"`
	Username    string      `gorm:"uniqueIndex;size:50;not null"`
	Name        string      `gorm:"size:100;null"`
	Phone       string      `gorm:"size:20;null"`
	Password    string      `gorm:"not null"`
	Email       string      `gorm:"size:100;null"`
	Role        string      `gorm:"size:20;not null;default:'user'"` //普通user, 管理员admin，填报员tby，项目管理员xmgly
	OpenID      string      `gorm:"size:100"`
	Points      uint        `gorm:"default:0"` //积分
	LastCheckIn *time.Time  `gorm:"default:null"` // 最后签到时间字段
	CreatedAt   time.Time
	UpdatedAt   time.Time
}

// 虚拟商品模型
type Product struct {
	ID              uint        `gorm:"primaryKey"`
	Name            string      `gorm:"size:100;not null"`  // 商品名称
	Photo           string      `gorm:"type:text;null;"`    // 缩略图
	Description datatypes.JSON                              // 商品描述
	Points          uint        `gorm:"not null"`           // 所需积分
	Stock           uint        `gorm:"not null"`           // 库存数量
	IsAvailable     bool        `gorm:"default:true"`       // 是否上架
	HiddenContent   string       `gorm:"type:text;null;comment:下单后可见内容"`
	CreatedAt       time.Time
	UpdatedAt       time.Time
}

// 购买记录模型
type Purchase struct {
	ID              uint    `gorm:"primaryKey"`
	UserID          uint    `gorm:"index;not null"`     // 用户ID
	ProductID       uint    `gorm:"index;not null"`     // 商品ID
	Quantity        uint    `gorm:"default:1"`          // 购买数量
	HiddenContent   string  `gorm:"type:text;null"`     // 存储商品快照的隐藏内容
	CreatedAt  time.Time
	// 关联用户和商品
	User    User    `gorm:"foreignKey:UserID"`
	Product Product `gorm:"foreignKey:ProductID"`
}

// 证书模板
type PicTemplate struct {
    ID              uint                `gorm:"primaryKey" json:"id"`
    Name            string              `gorm:"size:50;not null;index;"json:"name"`
    Xmid            uint                `json:"xmid" gorm:"comment:项目id"`
    BackgroundURL   string              `gorm:"type:varchar(255);not null;comment:背景图"json:"backgroundurl"`
    Fields          datatypes.JSON      `gorm:"type:json;comment:字段配置"json:"fields"`
    IsDefault       bool                `gorm:"default:false"json:"isdefault"`
    CreatedAt       time.Time
    UpdatedAt       time.Time
}

type Field struct {
    Name        string      `not null;"json:"name"`
    X           int         `not null;"json:"x"`
    Y           int         `not null;"json:"y"`
    FontSize    int         `not null;"json:"fontsize"`
    FontColor   string      `not null;"json:"fontcolor"`
    FontFamily  string      `not null;"json:"fontfamily"`
}

// 文章模型
type Blog struct {
	ID          uint            `gorm:"primaryKey"`
	Title       string          `gorm:"type:varchar(250);unique;index;comment:标题;"binding:"required"`
	Photo       string          `gorm:"type:varchar(250);null;comment:缩略图;"binding:"required"`
	IsRead      int             //阅读量
	IsOpen      bool            //是否开放阅读
	IsTop       bool            //是否置顶
	MultiFile   datatypes.JSON  //附件
	Content     datatypes.JSON  `gorm:"type:json;comment:内容;"`
	Cjz         string          `gorm:"type:varchar(50);default:admin;comment:作者;"`
	CreatedAt   time.Time
	UpdatedAt   time.Time
}

type ContentItem struct {
	Type  string `json:"type"`
	Value string `json:"value"`
	F     bool   `json:"f"`
}

type BlogListResponse struct {
	Items []Blog `json:"items"`
	Total int64        `json:"total"`
}

// 数据库存储选择图片
type FileRecord struct {
	ID          uint      `gorm:"primaryKey" json:"id"`
	FileName    string    `gorm:"size:255" json:"file_name"`
	FileURL     string    `gorm:"size:512" json:"url"`
	Folder      string    `gorm:"size:255;comment:所属文件夹" json:"folder"`
	CreatedAt   time.Time
}
type ImgListResponse struct {
	Items []FileRecord `json:"items"`
	Total int64        `json:"total"`
}

// word生成任务表
type DocGenTask struct {
    ID          uint        `gorm:"primaryKey" json:"id"`      
    Xmid        uint        `gorm:"column:xmid;Index"`      // bgsx项目id
    Progress    int         `gorm:"column:progress;"`       // 进度百分比
    Overwrite   string      `gorm:"column:overwrite;`       // 是否覆盖
    Field       string      `gorm:"column:field;`           // word字段
    Wjm         string      `gorm:"column:wjm;`             // 文件名字段
    Status      string      `gorm:"column:status"`          // 状态: pending/processing/completed/failed
    ErrorMsg    string      `gorm:"type:text; null; column:error_message"`   // 错误信息
    CreatedAt   time.Time
    UpdatedAt   time.Time
}

// 站内消息模型
type Message struct {
    ID        uint      `gorm:"primaryKey" json:"id"`
    UserID    uint      `gorm:"index;not null;comment:接收用户ID" json:"-"`
    Title     string    `gorm:"size:100;not null;comment:消息标题" json:"title"`
    Content   string    `gorm:"type:text;not null;comment:消息内容" json:"content"`
    IsRead    bool      `gorm:"default:false;comment:是否已读" json:"isRead"`
    CreatedAt time.Time `json:"createdAt"`
    UpdatedAt time.Time `json:"-"`
}

// 模板消息推送：短信、小程序、邮件
type MessageTemplate struct {
    ID         uint   `gorm:"primaryKey"`
    Type       string `gorm:"size:20;comment:类型(email/sms/miniprogram)"`
    Title      string 
    Content    string `gorm:"type:text"`       // 模板内容
    TemplateID string `gorm:"comment:第三方模板ID"`
    Variables  string `gorm:"comment:模板变量说明"`
}

// 购买积分订单
type OrderStatus string
const (
	OrderStatusPending  OrderStatus = "pending"
	OrderStatusSuccess  OrderStatus = "success"
	OrderStatusFailed   OrderStatus = "failed"
)

type Order struct {
	ID         uint        `gorm:"primaryKey"`
	UserID     uint                                                 // 关联用户
	OrderNo    string      `gorm:"type:varchar(255);uniqueIndex"`   // 唯一订单号
	Amount     float64                                              // 金额
	Points     int         // 积分
	Status     OrderStatus // 订单状态
	OpenID     string      // 微信 OpenID
	CreatedAt  time.Time
	UpdatedAt  time.Time
}

// 根据订单号查询
func GetOrderByNo(no string) (*Order, error) {
	var order Order
	if err := DB.Where("order_no = ?", no).First(&order).Error; err != nil {
		return nil, err
	}
	return &order, nil
}

// 根据id查询
func GetOrderByID(id uint) (*Order, error) {
	var order Order
	if err := DB.Where("id = ?", id).First(&order).Error; err != nil {
		return nil, err
	}
	return &order, nil
}

// 增加用户积分（事务内操作）
func AddUserPoints(tx *gorm.DB, userID uint, points int) error {
	return tx.Model(&User{}).Where("id = ?", userID).Update("points", gorm.Expr("points + ?", points)).Error
}